// Copyright (c) 2019 Presto Labs Pte. Ltd.
// Author: chensili

#pragma once

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "coin2/exchange/base/symbology/spot_product.h"
#include "coin2/exchange/base/symbology/util.h"

namespace coin2::exchange::upbit::symbology::util {

static std::optional<std::string> ToNativeCurrency(
    const std::string& currency_str) {
  const auto currency_str_upper = StringToUpperCopy(currency_str);
  std::string native_currency_str;
  if (currency_str_upper == "BCHSV") {
    native_currency_str = "BSV";
  } else if (currency_str_upper == "BCHABC" || currency_str_upper == "BCHN") {
    native_currency_str = "BCH";
  } else {
    native_currency_str = currency_str;
  }
  return native_currency_str;
}

static std::optional<std::string> FromNativeCurrency(
    const std::string& native_currency_str,
    int64_t resolve_timestamp) {
  const auto native_currency_str_upper = StringToUpperCopy(native_currency_str);
  if (native_currency_str_upper == "BSV") {
    return "BCHSV";
  } else if (native_currency_str_upper == "BCH") {
      if (resolve_timestamp >= base::symbology::BCHA_BCHN_FORK_TIME) {
        return "BCHN";
      } else {
        return "BCHABC";
      }
  } else {
    return native_currency_str_upper;
  }
}

template<typename TCurrency>
bool ParseUpbitNativeProduct(
    const std::string& product_str,
    int64_t resolve_timestamp,
    std::unique_ptr<TCurrency>* base_ptr,
    std::unique_ptr<TCurrency>* quote_ptr) {
  using base::market::MarketType;

  const std::string& product_str_upper = StringToUpperCopy(product_str);
  std::vector<std::string> splitted;
  splitted = Split(product_str_upper, "-");
  if (splitted.size() != 2) {
    return false;
  }

  *base_ptr = TCurrency::FromNativeStrNoThrow(splitted[1], resolve_timestamp);
  *quote_ptr = TCurrency::FromNativeStrNoThrow(splitted[0], resolve_timestamp);
  return true;
}

template<typename TCurrency>
std::string ToUpbitNativeProduct(
    const TCurrency& base,
    const TCurrency& quote) {
  using base::market::MarketType;

  std::stringstream ss;
  ss << quote.native_currency(MarketType::Spot) << '-' << base.native_currency(MarketType::Spot);
  return ss.str();
}

}  // namespace coin2::exchange::upbit::symbology::util
